/*
 * @Author: fengshan0525 2735332396@qq.com
 * @Date: 2023-03-19 15:53:45
 * @LastEditors: fengshan@0525 3183359488@qq.com
 * @LastEditTime: 2023-07-26 15:15:03
 * @FilePath: \nest-template\src\roles\roles.service.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { AmdinRole } from '@libs/db/models/role.model';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { IPaginationFormWithCondition } from 'types/requestParams';
import { AdminRoleMenu } from '@libs/db/models/role_menu.model';

@Injectable()
export class RolesService {
  constructor(
    @InjectModel('AmdinRole') private readonly roleModel: Model<AmdinRole>,
    @InjectModel('AdminRoleMenu')
    private readonly roleMenuModel: Model<AdminRoleMenu>,
  ) {}
  /**
   * @breif: 创建角色，创建角色文档的同时根据角色id创建角色-菜单文档，其中menus是个数组
   * @param {*} body
   * @return {*}
   */
  async create(body) {
    try {
      const hasRole = await this.roleModel
        .findOne({ $or: [{ roleId: body.roleId }, { roleKey: body.roleKey }] })
        .exec();
      if (hasRole) {
        throw new HttpException(
          '用户ID或用户权限字符重复!',
          HttpStatus.BAD_REQUEST,
        );
      }
      if (body.menus.length) {
        this.roleMenuModel.create({ roleId: body.roleId, menus: body.menus });
      }
      body.statusDetail = body.status == 1 ? '启用' : '停用';
      const doc = await this.roleModel.create(body);
      await doc.save();
      return '创建成功';
    } catch (e) {
      if (e.status === 400) {
        throw new HttpException(e, HttpStatus.BAD_REQUEST);
      } else {
        throw new HttpException(e, HttpStatus.INTERNAL_SERVER_ERROR);
      }
    }
  }

  // 根据id获取角色详情
  async getRole(id: number | string) {
    try {
      const doc = await this.roleModel.findOne(
        { roleId: id },
        { __v: 0, _id: 0 },
      );
      const menus = await this.roleMenuModel.findOne(
        { roleId: id },
        { menus: 1 },
      );
      const docParse = JSON.parse(JSON.stringify(doc));
      docParse.menus = menus.menus;
      return docParse;
    } catch (e) {
      throw new HttpException('未知错误', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  /**
   * @breif: 查询用户列表,可待条件，多条件查询
   * @param {IPaginationFormWithCondition} body
   * @return {*}
   */
  async findAll(body: IPaginationFormWithCondition) {
    try {
      const condition = [
        {
          $match: {
            $and: [
              { roleName: { $regex: body.roleName } }, // 角色名称
              { roleKey: { $regex: body.roleKey } }, // 权限字符
              { status: { $regex: body.status } }, // 状态
            ],
          },
        },
        {
          $facet: {
            total: [{ $count: 'count' }],
            rows: [
              { $skip: (body.pageNum - 1) * body.pageSize },
              { $limit: body.pageSize },
              { $project: { _id: 0, __v: 0 } },
            ],
          },
        },
        {
          $project: {
            list: '$rows',
            total: { $arrayElemAt: ['$total.count', 0] },
          },
        },
      ];
      const result = await this.roleModel.aggregate(condition);
      return result[0];
    } catch (e) {
      throw new HttpException('后台错误', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  /**
   * @breif: 更新角色
   * @param {*} body
   * @return {*}
   */
  async update(body) {
    try {
      body.statusDetail = body.status == 1 ? '启用' : '停用';
      await this.roleModel.updateOne({ roleId: body.roleId }, body).exec();
      await this.roleMenuModel.updateOne(
        { roleId: body.roleId },
        { menus: body.menus },
      );
      return '更新成功';
    } catch (e) {
      throw new HttpException('执行更新报错', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
  /**
   * @breif: 删除角色
   * @param {string} id
   * @return {*}
   */
  async remove(id: string | number) {
    try {
      await this.roleModel.deleteOne({ roleId: id });
      return '删除成功';
    } catch (e) {
      throw new HttpException('执行删除报错', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
